package com.docmgmt.mvp.controller;

import com.docmgmt.mvp.dto.*;
import com.docmgmt.mvp.exception.ForbiddenException;
import com.docmgmt.mvp.exception.UnauthorizedException;
import com.docmgmt.mvp.service.FileService;
import com.docmgmt.mvp.service.FileUploadService;
import com.docmgmt.mvp.service.PermissionService;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件管理控制器（v3.0 分片上传 + RBAC权限）
 */
@Slf4j
@RestController
@RequestMapping("/api/v1/files")
@RequiredArgsConstructor
public class FileController {

    private final FileUploadService fileUploadService;
    private final FileService fileService;
    private final PermissionService permissionService;

    /**
     * 普通文件上传（单文件）
     *
     * POST /api/v1/files/upload
     */
    @PostMapping("/upload")
    public Result<FileUploadResponse> upload(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "folderId", required = false) Long folderId,
            @RequestParam(value = "privacyLevel", required = false, defaultValue = "shared") String privacyLevel) {

        Long userId = getCurrentUserId();

        // 权限检查：file:create
        if (!permissionService.checkPermission(userId, "file", "create")) {
            throw new ForbiddenException("无权限上传文件");
        }

        log.info("POST /api/v1/files/upload - userId={}, fileName={}, size={}",
                userId, file.getOriginalFilename(), file.getSize());

        FileUploadResponse response = fileUploadService.upload(file, userId, folderId, privacyLevel);
        return Result.success("文件上传成功", response);
    }

    // ==================== 分片上传（v3.0新增） ====================

    /**
     * 初始化分片上传
     *
     * POST /api/v1/files/chunk/init
     */
    @PostMapping("/chunk/init")
    public Result<String> initChunkUpload(
            @RequestParam("fileName") String fileName,
            @RequestParam("fileSize") Long fileSize,
            @RequestParam("totalChunks") Integer totalChunks) {

        Long userId = getCurrentUserId();

        // 权限检查
        if (!permissionService.checkPermission(userId, "file", "create")) {
            throw new ForbiddenException("无权限上传文件");
        }

        log.info("POST /api/v1/files/chunk/init - userId={}, fileName={}, fileSize={}, totalChunks={}",
                userId, fileName, fileSize, totalChunks);

        String uploadId = fileUploadService.initChunkUpload(userId, fileName, fileSize, totalChunks);
        return Result.success("分片上传会话已创建", uploadId);
    }

    /**
     * 上传单个分片
     *
     * POST /api/v1/files/chunk/upload
     */
    @PostMapping("/chunk/upload")
    public Result<Void> uploadChunk(
            @RequestParam("uploadId") String uploadId,
            @RequestParam("chunkIndex") Integer chunkIndex,
            @RequestParam("chunk") MultipartFile chunkFile) {

        Long userId = getCurrentUserId();

        log.info("POST /api/v1/files/chunk/upload - userId={}, uploadId={}, chunkIndex={}",
                userId, uploadId, chunkIndex);

        fileUploadService.uploadChunk(uploadId, chunkIndex, chunkFile);
        return Result.success("分片上传成功");
    }

    /**
     * 合并分片
     *
     * POST /api/v1/files/chunk/merge
     */
    @PostMapping("/chunk/merge")
    public Result<FileUploadResponse> mergeChunks(
            @RequestParam("uploadId") String uploadId,
            @RequestParam(value = "folderId", required = false) Long folderId,
            @RequestParam(value = "privacyLevel", required = false, defaultValue = "shared") String privacyLevel) {

        Long userId = getCurrentUserId();

        log.info("POST /api/v1/files/chunk/merge - userId={}, uploadId={}", userId, uploadId);

        FileUploadResponse response = fileUploadService.mergeChunks(uploadId, userId, folderId, privacyLevel);
        return Result.success("文件上传完成", response);
    }

    // ==================== 文件操作 ====================

    /**
     * 4.1.1 秒传检查
     *
     * POST /api/v1/files/upload/check
     */
    @PostMapping("/upload/check")
    public Result<FileUploadCheckResponse> checkUpload(
            @Valid @RequestBody FileUploadCheckRequest request) {
        Long userId = getCurrentUserId();

        log.info("POST /api/v1/files/upload/check - userId={}, md5={}, size={}",
                userId, request.getMd5(), request.getSize());

        FileUploadCheckResponse response = fileService.checkFileUpload(
                request.getMd5(), request.getSize(), userId, request.getFolderId());
        return Result.success(response.getCanSkipUpload() ? "文件已存在，秒传成功" : "文件不存在，请上传", response);
    }

    /**
     * 4.2.1 查询文件列表（增强版）
     *
     * GET /api/v1/files?folderId=&keyword=&extension=&page=1&pageSize=20
     */
    @GetMapping
    public Result<PagedResult<FileVO>> listFiles(
            @RequestParam(required = false) Long folderId,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String extension,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "20") Integer pageSize,
            @RequestParam(defaultValue = "createdAt") String sortBy,
            @RequestParam(defaultValue = "desc") String sortOrder) {
        Long userId = getCurrentUserId();

        log.info("GET /api/v1/files - userId={}, folderId={}, keyword={}, extension={}",
                userId, folderId, keyword, extension);

        PagedResult<FileVO> result = fileService.listFilesEnhanced(
                userId, folderId, keyword, extension, page, pageSize, sortBy, sortOrder);
        return Result.success("查询成功", result);
    }

    /**
     * 4.3.2 预览文件
     *
     * GET /api/v1/files/{id}/preview
     */
    @GetMapping("/{fileId}/preview")
    public Result<String> previewFile(@PathVariable Long fileId) {
        Long userId = getCurrentUserId();

        // 权限检查：file:read
        if (!permissionService.checkPermission(userId, "file:" + fileId, "read")) {
            throw new ForbiddenException("无权限预览该文件");
        }

        log.info("GET /api/v1/files/{}/preview - userId={}", fileId, userId);

        String previewUrl = fileService.getFilePreview(fileId);
        return Result.success("预览链接已生成", previewUrl);
    }

    /**
     * 4.3.3 重命名文件
     *
     * PUT /api/v1/files/{id}/rename
     */
    @PutMapping("/{fileId}/rename")
    public Result<FileVO> renameFile(
            @PathVariable Long fileId,
            @Valid @RequestBody RenameFileRequest request) {
        Long userId = getCurrentUserId();

        // 权限检查：file:update
        if (!permissionService.checkPermission(userId, "file:" + fileId, "update")) {
            throw new ForbiddenException("无权限修改该文件");
        }

        log.info("PUT /api/v1/files/{}/rename - userId={}, newName={}",
                fileId, userId, request.getNewName());

        FileVO file = fileService.renameFile(fileId, request.getNewName(), userId);
        return Result.success("文件重命名成功", file);
    }

    /**
     * 4.3.4 移动文件
     *
     * PUT /api/v1/files/{id}/move
     */
    @PutMapping("/{fileId}/move")
    public Result<FileVO> moveFile(
            @PathVariable Long fileId,
            @Valid @RequestBody MoveFileRequest request) {
        Long userId = getCurrentUserId();

        // 权限检查：file:update
        if (!permissionService.checkPermission(userId, "file:" + fileId, "update")) {
            throw new ForbiddenException("无权限移动该文件");
        }

        log.info("PUT /api/v1/files/{}/move - userId={}, targetFolderId={}",
                fileId, userId, request.getTargetFolderId());

        FileVO file = fileService.moveFile(fileId, request.getTargetFolderId(), userId);
        return Result.success("文件移动成功", file);
    }

    /**
     * 4.3.5 复制文件
     *
     * POST /api/v1/files/{id}/copy
     */
    @PostMapping("/{fileId}/copy")
    public Result<FileVO> copyFile(
            @PathVariable Long fileId,
            @Valid @RequestBody CopyFileRequest request) {
        Long userId = getCurrentUserId();

        // 权限检查：file:read
        if (!permissionService.checkPermission(userId, "file:" + fileId, "read")) {
            throw new ForbiddenException("无权限复制该文件");
        }

        log.info("POST /api/v1/files/{}/copy - userId={}, targetFolderId={}, newName={}",
                fileId, userId, request.getTargetFolderId(), request.getNewName());

        FileVO file = fileService.copyFile(fileId, request.getTargetFolderId(), request.getNewName(), userId);
        return Result.success("文件复制成功", file);
    }

    /**
     * 4.3.7 批量操作
     *
     * POST /api/v1/files/batch
     */
    @PostMapping("/batch")
    public Result<BatchFileResponse> batchOperation(
            @Valid @RequestBody BatchFileRequest request) {
        Long userId = getCurrentUserId();

        log.info("POST /api/v1/files/batch - userId={}, action={}, fileIds={}",
                userId, request.getAction(), request.getFileIds());

        BatchFileResponse response = fileService.batchOperation(
                request.getAction(), request.getFileIds(), request.getTargetFolderId(), userId);
        return Result.success("批量操作完成", response);
    }

    /**
     * 获取文件信息
     *
     * GET /api/v1/files/{fileId}
     */
    @GetMapping("/{fileId}")
    public Result<FileVO> getFileInfo(@PathVariable Long fileId) {
        Long userId = getCurrentUserId();

        // 权限检查：file:read
        if (!permissionService.checkPermission(userId, "file:" + fileId, "read")) {
            throw new ForbiddenException("无权限查看该文件");
        }

        log.info("GET /api/v1/files/{} - userId={}", fileId, userId);

        FileVO fileVO = fileService.getFileDetail(fileId);
        return Result.success(fileVO);
    }

    /**
     * 删除文件
     *
     * DELETE /api/v1/files/{fileId}
     */
    @DeleteMapping("/{fileId}")
    public Result<Void> deleteFile(@PathVariable Long fileId) {
        Long userId = getCurrentUserId();

        // 权限检查：file:delete
        if (!permissionService.checkPermission(userId, "file:" + fileId, "delete")) {
            throw new ForbiddenException("无权限删除该文件");
        }

        log.info("DELETE /api/v1/files/{} - userId={}", fileId, userId);

        fileService.deleteFile(fileId, userId);
        return Result.success("文件删除成功");
    }

    /**
     * 下载文件
     *
     * GET /api/v1/files/{fileId}/download
     */
    @GetMapping("/{fileId}/download")
    public Result<String> downloadFile(@PathVariable Long fileId) {
        Long userId = getCurrentUserId();

        // 权限检查：file:download
        if (!permissionService.checkPermission(userId, "file:" + fileId, "download")) {
            throw new ForbiddenException("无权限下载该文件");
        }

        log.info("GET /api/v1/files/{}/download - userId={}", fileId, userId);

        // 生成临时下载URL（实际应该返回MinIO的presigned URL）
        String downloadUrl = fileService.generateDownloadUrl(fileId);
        return Result.success("下载链接已生成", downloadUrl);
    }

    /**
     * 从Spring Security上下文获取当前用户ID
     */
    private Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new UnauthorizedException("未登录或认证已过期");
        }

        Object principal = authentication.getPrincipal();
        if (principal instanceof Long) {
            return (Long) principal;
        }

        throw new UnauthorizedException("无效的认证信息");
    }
}
